home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr53 / 251_01.zip / ADVDBS.C < prev    next >
Text File  |  1993-04-01  |  11KB  |  485 lines

  1. /* advdbs.c - adventure database access routines */
  2. /*
  3.     Copyright (c) 1986, by David Michael Betz
  4.     All rights reserved
  5. */
  6.  
  7. #include "advint.h"
  8. #include "advdbs.h"
  9. #ifdef MAC
  10. #include <fnctl.h>
  11. #define RMODE    (O_RDONLY|O_BINARY)
  12. #else
  13. #include <setjmp.h>
  14. #define RMODE    0
  15. #endif
  16.  
  17. /* global variables */
  18. int h_init;    /* initialization code */
  19. int h_update;    /* update code */
  20. int h_before;    /* before handler code */
  21. int h_after;    /* after handler code */
  22. int h_error;    /* error handling code */
  23. int datafd;    /* data file descriptor */
  24.  
  25. /* external variables */
  26. extern jmp_buf restart;
  27.  
  28. /* external routines */
  29. extern char *malloc();
  30.  
  31. /* table base addresses */
  32. char *wtable;    /* word table */
  33. char *wtypes;    /* word type table */
  34. int wcount;    /* number of words */
  35. char *otable;    /* object table */
  36. int ocount;    /* number of objects */
  37. char *atable;    /* action table */
  38. int acount;    /* number of actions */
  39. char *vtable;    /* variable table */
  40. int vcount;    /* number of variables */
  41. char *data;    /* base of data tables */
  42. char *base;    /* current base address */
  43. char *dbase;    /* base of the data space */
  44. char *cbase;    /* base of the code space */
  45. int length;    /* length of resident data structures */
  46.  
  47. /* data file header */
  48. static char hdr[HDR_SIZE];
  49.  
  50. /* save parameters */
  51. static long saveoff;    /* save data file offset */
  52. static char *save;    /* save area base address */
  53. static int slen;    /* save area length */
  54.  
  55. /* db_init - read and decode the data file header */
  56. db_init(name)
  57.   char *name;
  58. {
  59.     int woff,ooff,aoff,voff,n;
  60.     char fname[50];
  61.  
  62.     /* get the data file name */
  63.     strcpy(fname,name);
  64. #ifndef MAC
  65.     strcat(fname,".dat");
  66. #endif
  67.  
  68.     /* open the data file */
  69.     if ((datafd = open(fname,RMODE)) == -1)
  70.     error("can't open data file");
  71.  
  72.     /* read the header */
  73.     if (read(datafd,hdr,HDR_SIZE) != HDR_SIZE)
  74.     error("bad data file");
  75.     complement(hdr,HDR_SIZE);
  76.     base = hdr;
  77.  
  78.     /* check the magic information */
  79.     if (strncmp(&hdr[HDR_MAGIC],"ADVSYS",6) != 0)
  80.     error("not an adventure data file");
  81.  
  82.     /* check the version number */
  83.     if ((n = getword(HDR_VERSION)) < 101 || n > VERSION)
  84.     error("wrong version number");
  85.  
  86.     /* decode the resident data length header field */
  87.     length = getword(HDR_LENGTH);
  88.  
  89.     /* allocate space for the resident data structure */
  90.     if ((data = malloc(length)) == 0)
  91.     error("insufficient memory");
  92.  
  93.     /* compute the offset to the data */
  94.     saveoff = (long)getword(HDR_DATBLK) * 512L;    
  95.  
  96.     /* read the resident data structure */
  97.     lseek(datafd,saveoff,0);
  98.     if (read(datafd,data,length) != length)
  99.     error("bad data file");
  100.     complement(data,length);
  101.  
  102.     /* get the table base addresses */
  103.     wtable = data + (woff = getword(HDR_WTABLE));
  104.     wtypes = data + getword(HDR_WTYPES) - 1;
  105.     otable = data + (ooff = getword(HDR_OTABLE));
  106.     atable = data + (aoff = getword(HDR_ATABLE));
  107.     vtable = data + (voff = getword(HDR_VTABLE));
  108.  
  109.     /* get the save data area */
  110.     saveoff += (long)getword(HDR_SAVE);
  111.     save = data + getword(HDR_SAVE);
  112.     slen = getword(HDR_SLEN);
  113.  
  114.     /* get the base of the data and code spaces */
  115.     dbase = data + getword(HDR_DBASE);
  116.     cbase = data + getword(HDR_CBASE);
  117.  
  118.     /* initialize the message routines */
  119.     msg_init(datafd,getword(HDR_MSGBLK));
  120.  
  121.     /* get the code pointers */
  122.     h_init = getword(HDR_INIT);
  123.     h_update = getword(HDR_UPDATE);
  124.     h_before = getword(HDR_BEFORE);
  125.     h_after = getword(HDR_AFTER);
  126.     h_error = getword(HDR_ERROR);
  127.  
  128.     /* get the table lengths */
  129.     base = data;
  130.     wcount = getword(woff); 
  131.     ocount = getword(ooff);
  132.     acount = getword(aoff);
  133.     vcount = getword(voff);
  134.  
  135.     /* setup the base of the resident data */
  136.     base = dbase;
  137.  
  138.     /* set the object count */
  139.     setvalue(V_OCOUNT,ocount);
  140. }
  141.  
  142. /* db_save - save the current database */
  143. db_save(name)
  144.   char *name;
  145. {
  146.     return (advsave(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
  147. }
  148.  
  149. /* db_restore - restore a saved database */
  150. int db_restore(name)
  151.   char *name;
  152. {
  153.     return (advrestore(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
  154. }
  155.  
  156. /* db_restart - restart the current game */
  157. db_restart()
  158. {
  159.     lseek(datafd,saveoff,0);
  160.     if (read(datafd,save,slen) != slen)
  161.     return (NIL);
  162.     complement(save,slen);
  163.     setvalue(V_OCOUNT,ocount);
  164.     longjmp(restart,1);
  165. }
  166.  
  167. /* complement - complement a block of memory */
  168. complement(adr,len)
  169.   char *adr; int len;
  170. {
  171.     for (; len--; adr++)
  172.     *adr = ~(*adr + 30);
  173. }
  174.  
  175. /* findword - find a word in the dictionary */
  176. int findword(word)
  177.   char *word;
  178. {
  179.     char sword[WRDSIZE+1];
  180.     int wrd,i;
  181.  
  182.     /* shorten the word */
  183.     strncpy(sword,word,WRDSIZE); sword[WRDSIZE] = 0;
  184.  
  185.     /* look up the word */
  186.     for (i = 1; i <= wcount; i++) {
  187.     wrd = getwloc(i);
  188.     if (strcmp(base+wrd+2,sword) == 0)
  189.         return (getword(wrd));
  190.     }
  191.     return (NIL);
  192. }
  193.  
  194. /* wtype - return the type of a word */
  195. int wtype(wrd)
  196.   int wrd;
  197. {
  198.     return (wtypes[wrd]);
  199. }
  200.  
  201. /* match - match an object against a name and list of adjectives */
  202. int match(obj,noun,adjs)
  203.   int obj,noun,*adjs;
  204. {
  205.     int *aptr;
  206.  
  207.     if (!hasnoun(obj,noun))
  208.     return (FALSE);
  209.     for (aptr = adjs; *aptr != NIL; aptr++)
  210.     if (!hasadjective(obj,*aptr))
  211.         return (FALSE);
  212.     return (TRUE);
  213. }
  214.  
  215. /* checkverb - check to see if this is a valid verb */
  216. int checkverb(verbs)
  217.   int *verbs;
  218. {
  219.     int act;
  220.  
  221.     /* look up the action */
  222.     for (act = 1; act <= acount; act++)
  223.     if (hasverb(act,verbs))
  224.         return (act);
  225.     return (NIL);
  226. }
  227.  
  228. /* findaction - find an action matching a description */
  229. findaction(verbs,preposition,flag)
  230.   int *verbs,preposition,flag;
  231. {
  232.     int act,mask;
  233.  
  234.     /* look up the action */
  235.     for (act = 1; act <= acount; act++) {
  236.     if (preposition && !haspreposition(act,preposition))
  237.         continue;
  238.     if (!hasverb(act,verbs))
  239.         continue;
  240.     mask = ~getabyte(act,A_MASK);
  241.     if ((flag & mask) == (getabyte(act,A_FLAG) & mask))
  242.         return (act);
  243.     }
  244.     return (NIL);
  245. }
  246.  
  247. /* getp - get the value of an object property */
  248. int getp(obj,prop)
  249.   int obj,prop;
  250. {
  251.     int p;
  252.  
  253.     for (; obj; obj = getofield(obj,O_CLASS))
  254.     if (p = findprop(obj,prop))
  255.         return (getofield(obj,p));
  256.     return (NIL);
  257. }
  258.  
  259. /* setp - set the value of an object property */
  260. int setp(obj,prop,val)
  261.   int obj,prop,val;
  262. {
  263.     int p;
  264.  
  265.     for (; obj; obj = getofield(obj,O_CLASS))
  266.     if (p = findprop(obj,prop))
  267.         return (putofield(obj,p,val));
  268.     return (NIL);
  269. }
  270.  
  271. /* findprop - find a property */
  272. int findprop(obj,prop)
  273.   int obj,prop;
  274. {
  275.     int n,i,p;
  276.  
  277.     n = getofield(obj,O_NPROPERTIES);
  278.     for (i = p = 0; i < n; i++, p += 4)
  279.     if ((getofield(obj,O_PROPERTIES+p) & ~P_CLASS) == prop)
  280.         return (O_PROPERTIES+p+2);
  281.     return (NIL);
  282. }
  283.  
  284. /* hasnoun - check to see if an object has a specified noun */
  285. int hasnoun(obj,noun)
  286.   int obj,noun;
  287. {
  288.     while (obj) {
  289.     if (inlist(getofield(obj,O_NOUNS),noun))
  290.         return (TRUE);
  291.     obj = getofield(obj,O_CLASS);
  292.     }
  293.     return (FALSE);
  294. }
  295.  
  296. /* hasadjective - check to see if an object has a specified adjective */
  297. int hasadjective(obj,adjective)
  298.   int obj,adjective;
  299. {
  300.     while (obj) {
  301.     if (inlist(getofield(obj,O_ADJECTIVES),adjective))
  302.         return (TRUE);
  303.     obj = getofield(obj,O_CLASS);
  304.     }
  305.     return (FALSE);
  306. }
  307.  
  308. /* hasverb - check to see if this action has this verb */
  309. int hasverb(act,verbs)
  310.   int act,*verbs;
  311. {
  312.     int link,word,*verb;
  313.  
  314.     /* get the list of verbs */
  315.     link = getafield(act,A_VERBS);
  316.  
  317.     /* look for this verb */
  318.     while (link != NIL) {
  319.     verb = verbs;
  320.     word = getword(link+L_DATA);
  321.     while (*verb != NIL && word != NIL) {
  322.         if (*verb != getword(word+L_DATA))
  323.         break;
  324.         verb++;
  325.         word = getword(word+L_NEXT);
  326.     }
  327.     if (*verb == NIL && word == NIL)
  328.         return (TRUE);
  329.     link = getword(link+L_NEXT);
  330.     }
  331.     return (FALSE);
  332. }
  333.  
  334. /* haspreposition - check to see if an action has a specified preposition */
  335. int haspreposition(act,preposition)
  336.   int act,preposition;
  337. {
  338.     return (inlist(getafield(act,A_PREPOSITIONS),preposition));
  339. }
  340.  
  341. /* inlist - check to see if a word is an element of a list */
  342. int inlist(link,word)
  343.   int link,word;
  344. {
  345.     while (link != NIL) {
  346.     if (word == getword(link+L_DATA))
  347.         return (TRUE);
  348.     link = getword(link+L_NEXT);
  349.     }
  350.     return (FALSE);
  351. }
  352.  
  353. /* getofield - get a field from an object */
  354. int getofield(obj,off)
  355.   int obj,off;
  356. {
  357.     return (getword(getoloc(obj)+off));
  358. }
  359.  
  360. /* putofield - put a field into an object */
  361. int putofield(obj,off,val)
  362.   int obj,off,val;
  363. {
  364.     return (putword(getoloc(obj)+off,val));
  365. }
  366.  
  367. /* getafield - get a field from an action */
  368. int getafield(act,off)
  369.   int act,off;
  370. {
  371.     return (getword(getaloc(act)+off));
  372. }
  373.  
  374. /* getabyte - get a byte field from an action */
  375. int getabyte(act,off)
  376.   int act,off;
  377. {
  378.     return (getbyte(getaloc(act)+off));
  379. }
  380.  
  381. /* getoloc - get an object from the object table */
  382. int getoloc(n)
  383.   int n;
  384. {
  385.     if (n < 1 || n > ocount)
  386.     nerror("object number out of range: %d",n);
  387.     return (getdword(otable+n+n));
  388. }
  389.  
  390. /* getaloc - get an action from the action table */
  391. int getaloc(n)
  392.   int n;
  393. {
  394.     if (n < 1 || n > acount)
  395.     nerror("action number out of range: %d",n);
  396.     return (getdword(atable+n+n));
  397. }
  398.  
  399. /* getvalue - get the value of a variable from the variable table */
  400. int getvalue(n)
  401.   int n;
  402. {
  403.     if (n < 1 || n > vcount)
  404.     nerror("variable number out of range: %d",n);
  405.     return (getdword(vtable+n+n));
  406. }
  407.  
  408. /* setvalue - set the value of a variable in the variable table */
  409. int setvalue(n,v)
  410.   int n,v;
  411. {
  412.     if (n < 1 || n > vcount)
  413.     nerror("variable number out of range: %d",n);
  414.     return (putdword(vtable+n+n,v));
  415. }
  416.  
  417. /* getwloc - get a word from the word table */
  418. int getwloc(n)
  419.   int n;
  420. {
  421.     if (n < 1 || n > wcount)
  422.     nerror("word number out of range: %d",n);
  423.     return (getdword(wtable+n+n));
  424. }
  425.  
  426. /* getword - get a word from the data array */
  427. int getword(n)
  428.   int n;
  429. {
  430.     return (getdword(base+n));
  431. }
  432.  
  433. /* putword - put a word into the data array */
  434. int putword(n,w)
  435.   int n,w;
  436. {
  437.     return (putdword(base+n,w));
  438. }
  439.  
  440. /* getbyte - get a byte from the data array */
  441. int getbyte(n)
  442.   int n;
  443. {
  444.     return (*(base+n) & 0xFF);
  445. }
  446.  
  447. /* getcbyte - get a code byte */
  448. int getcbyte(n)
  449.   int n;
  450. {
  451.     return (*(cbase+n) & 0xFF);
  452. }
  453.  
  454. /* getcword - get a code word */
  455. int getcword(n)
  456.   int n;
  457. {
  458.     return (getdword(cbase+n));
  459. }
  460.  
  461. /* getdword - get a word from the data array */
  462. int getdword(p)
  463.   char *p;
  464. {
  465.     return ((*p & 0xFF) | (*(p+1) << 8));
  466. }
  467.  
  468. /* putdword - put a word into the data array */
  469. int putdword(p,w)
  470.   char *p; int w;
  471. {
  472.     *p = w; *(p+1) = w >> 8;
  473.     return (w);
  474. }
  475.  
  476. /* nerror - handle errors with numeric arguments */
  477. nerror(fmt,n)
  478.   char *fmt; int n;
  479. {
  480.     char buf[100];
  481.     sprintf(buf,fmt,n);
  482.     error(buf);
  483. }
  484.  
  485.